[% setvar title Additions to 'use strict' to fix syntactic ambiguities %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Additions to 'use strict' to fix syntactic ambiguities</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>   Maintainer: Nathan Wiger &lt;<a href='mailto:nate@wiger.org'>nate@wiger.org</a>&gt;
   Date: 24 Sep 2000
   Last Modified: 30 Sep 2000
   Mailing List: <a href='mailto:perl6-language@perl.org'>perl6-language@perl.org</a>
   Number: 278
   Version: 2
   Status: Frozen</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>Several RFCs and many people have voiced concerns with different parts
of Perl's syntax. Most take issue with syntactic ambiguities and the
inability to easily tokenize Perl.</p>
<p>This RFC shows how these all boil down to a three central issues, and
how they can be solved with some simple additions to <code>use strict</code>. By
default, Perl should remain as flexible as possible. By adding these
flags to <code>use strict</code>, those who desire them can have all the benefits
of a stricter syntax, without hurting those that like these features.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<a name='The Problems'></a><h2>The Problems</h2>
<a name='Indirect Objects'></a><h3>Indirect Objects</h3>
<p>RFC 244 proposes eliminating the bareword indirect object syntax because
this:</p>
<pre>   print STDERR @stuff;</pre>
<p>Can be parsed as either of these:</p>
<pre>   STDERR-&gt;print(@stuff);
   print(STDERR(@stuff));</pre>
<p>Depending on your usage of <code>STDERR</code> other places in your program.
However, many of us like writing:</p>
<pre>   $q = new CGI;</pre>
<p>Quite a bit, and consider this DWIMish.</p>
<a name='Barewords vs. Functions'></a><h3>Barewords vs. Functions</h3>
<p>RFC 244 and others mention several problems with barewords such as:</p>
<pre>   Class-&gt;stuff(@args);   # Class()-&gt;stuff or 'Class'-&gt;stuff ?</pre>
<p>Again, the fact that Perl can figure this out correctly is quite
DWIMish, and this functionality should not be removed by default.</p>
<a name='Special Cases'></a><h3>Special Cases</h3>
<p>Many special cases abound, such as the bare <code>//</code> mentioned in RFC 135.
Again, this is stuff that makes Perl fun, and should not be taken out
of the language.</p>
<a name='The Solutions'></a><h2>The Solutions</h2>
<p>At first, these may not seem related. However, they very much are, and
in fact all boil down to only three issues which can be resolved with
additions to <code>use strict</code>.</p>
<a name='Function Parens - use strict 'words''></a><h3>Function Parens - <code>use strict 'words'</code></h3>
<p>This imposes a very simple restriction: barewords are not allowed. They
must be either quoted or specified with parens to indicate they are
functions. Note this solves the <code>%SIG</code> problem from Camel:</p>
<pre>   use strict 'words';
   $SIG{PIPE} = Plumber;    # syntax error
   $SIG{PIPE} = &quot;Plumber&quot;;  # use main::Plumber
   $SIG{PIPE} = Plumber();  # call Plumber()</pre>
<p>In addition, this also forces users to disambiguate certain functions:</p>
<pre>   use strict 'words';

   name-&gt;stuff(@args);      # syntax error
   'name'-&gt;stuff(@args);    # 'name'-&gt;stuff
   name::-&gt;stuff(@args);    # ok too, same thing
   name()-&gt;stuff(@args);    # name()-&gt;stuff

   $result = value + 42;    # syntax error
   $result = value() + 42;  # value() + 42
   $result = value(  + 42); # value(42)
   $result = 'value' + 42;  # ok, if you think this is Java...</pre>
<p>It's simple: barewords are not allowed.</p>
<a name='Indirect Objects - use strict 'objects''></a><h3>Indirect Objects - <code>use strict 'objects'</code></h3>
<p>Another major problem is ambiguous indirect objects. Under <code>use strict
'objects'</code>, the indirect object <i>must</i> be surrounded by braces:</p>
<pre>   use strict 'objects';
   no strict 'words';

   print STDERR @stuff;     # print(STDERR(@stuff))
   print 'STDERR' @stuff;   # syntax error
   print {'STDERR'} @stuff; # 'STDERR'-&gt;print(@stuff)

   print $fh @junk;         # syntax error
   print {$fh} @junk;       # $fh-&gt;print(@junk)</pre>
<p>This eliminates the possibility of ambiguity with indirect objects. When
combined with <code>strict 'words'</code>, code becomes even less ambiguous:</p>
<pre>   use strict qw(words objects);

   $q = new 'CGI';          # syntax error
   $q = new {'CGI'};        # 'CGI'-&gt;new
   $q = new ('CGI');        # new('CGI')
   $q = new (CGI());        # new(CGI())

   $q = new 'CGI' @args;    # syntax error
   $q = new {'CGI'} (@args);# 'CGI'-&gt;new(@args)
   $q = new (CGI (@args));  # new(CGI(@args))</pre>
<a name='Syntactic Problems - use strict 'syntax''></a><h3>Syntactic Problems - <code>use strict 'syntax'</code></h3>
<p>There are many other &quot;little ambiguities&quot; throughout Perl. Adding
<code>strict 'syntax'</code> would remove these and require the user to specify
them explicitly. In this category fits the bare <code>//</code> problem mentioned
in RFC 135, as well as several common &quot;bugs&quot; (mistakes).</p>
<p>Under this rule, the following would apply:</p>
<pre>   1. No more // by itself, you must use m//

   2. Trailing conditionals would require parens

   3. Precedence other than for basic math and boolean ops would
      not apply</pre>
<p>This is designed to force you to write clean, unambiguous code that
borders on being non-Perlish:</p>
<pre>   use strict 'syntax';
   next if /^#/ || /^$/;       # syntax error
   next if m/^#/ || m/^$/;     # syntax error
   next if (m/^#/ || m/^$/);   # ok

   use strict 'syntax';
   $data = $a + $b / $c - $d || $default or die;      # no way
   $data = ($a + $b / $c - $d) || $default or die;    # nope
   ($data = ($a + $b / $c - $d) || $default) or die;  # ok</pre>
<p>Basically, the idea is to impose a truly unambiguous style so that
people don't get carried away with precedence and special cases.</p>
<a name='Combining all these together'></a><h2>Combining all these together</h2>
<p>Let's look at an example of how all these would be combined. With the
additions to <code>use strict</code> proposed in this RFC, the existing Perl 5
code snippet:</p>
<pre>   $r = Apache-&gt;request;

   sub geturl {
       shift-&gt;{DATA}-&gt;{uri};
   }

   sub seturl {
       shift-&gt;{DATA}-&gt;{uri} = $_[0];
   }

   seturl $r-&gt;uri;
   print STDERR geturl or die &quot;Can't print to STDERR: $!\n&quot;;</pre>
<p>Would have to be rewritten:</p>
<pre>   use strict;

   my $r = Apache::-&gt;request();

   sub geturl {
       shift()-&gt;{DATA}-&gt;{uri};
   }

   sub seturl {
       shift()-&gt;{DATA}-&gt;{uri} = $_[0];
   }

   seturl($r-&gt;uri());
   print {'STDERR'} (geturl()) or die(&quot;Can't print to STDERR: $!\n&quot;);</pre>
<p>The syntax remains consistent, even though it's much more strict. If you
don't like a particular aspect, such as indirect objects requiring
braces, you can always turn that off with <code>no strict</code>.</p>
<a name='Problems with RFC 244 and special-casing -&gt;'></a><h2>Problems with RFC 244 and special-casing -&gt;</h2>
<p>While syntactic ambiguities are problems in Perl, going about it in the
way that RFC 244 proposes - by special-casing -&gt; and bareword indirect
objects - is not the solution. In the process it introduces new
syntactic ambiguities, where sometimes a bareword is a function and
other times it's a word, depending on context:</p>
<pre>   print STDERR @data;            # error?
   print 'STDERR' @data;          # syntax error
   print {'STDERR'} @data;        # Joe Scripter: &quot;huh?!&quot;

   $u = Apache-&gt;request-&gt;uri;     # error?
   $u = Apache-&gt;request()-&gt;uri;   # huh? parens just in the middle?</pre>
<p>Particularly annoying is that last one, since the second to last cannot
involve ambiguity because of its context. However, an approach like RFC
244's would require us to explicitly use the last form, even where it
wouldn't be needed.</p>
<p>Instead, we need to attack the real problem: The ambiguity throughout
Perl between unquoted barewords and functions.</p>
<p>Perl 6 should remain as flexible as Perl 5 by default, so that people
don't run away screaming. To tighten up code on important apps, the
above rules can simply be invoked with <code>use strict</code>:</p>
<pre>   use strict;

   print {'STDERR'} @data;              # works, is 'STDERR'-&gt;print
   my $u = Apache::-&gt;request()-&gt;uri();  # works, and more consistent</pre>
<p>Plus, <code>use strict</code> is lexically scoped, allowing us to have blocks of
loosely-evaluated code mixed with strict code, and vice versa.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>New hooks in <code>use strict</code>.</p>
<a name='MIGRATION'></a><h1>MIGRATION</h1>
<p>Simplest case: For those scripts that have a <code>use strict</code>, add a <code>no
strict qw(words objects syntax)</code> right after it. Then code doesn't have
to be changed.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>RFC 244: Method calls should not suffer from the action on a distance</p>
<p>RFC 277: Method calls SHOULD suffer from ambiguity by default</p>
<p>perl6storm issues #0003, #0035, #0050</p>
</div>
